package com.atguigu.lease.common.utils;

import com.atguigu.lease.common.exception.LeaseException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.CompressionCodecs;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.util.Date;

public class JwtUtil {
    //   静态属性 token过期时间，单位毫秒
    private static long tokenExpiration = 60 * 60 * 1000L;
    //    静态属性 token签名密钥
    private static SecretKey tokenSignKey = Keys.hmacShaKeyFor("M0PKKI6pYGVWWfDZw90a0lTpGYX1d4AQ".getBytes());

    //    创建token方法
    //    需要传过来用户id和用户名
    public static String createToken(Long userId, String username) {
//        创建token 需要三步骤
//        1. 设置头部信息
//        2. 设置负载信息
//        3. 设置签名信息
//        Jwts中 setExpiration(new Date(System.currentTimeMillis() + tokenExpiration)) 设置过期时间
//        Jwts中 setSubject("user_login_token") 设置头部信息
//        Jwts中 claim("userId", userId) 设置负载信息
//        Jwts中 claim("username", username) 设置负载信息
//        Jwts中 signWith(tokenSignKey) 设置签名信息
//        Jwts中 compressWith(CompressionCodecs.GZIP) 设置压缩信格式息
//        Jwts中 compact() 生成token
        String token = Jwts.builder().setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))
                .setSubject("user_login_token")
                .claim("userId", userId)
                .claim("userName", username)
                .signWith(tokenSignKey)
                .compressWith(CompressionCodecs.GZIP)
                .compact();
        return token;
    }

    //    解析token方法
    public static Claims parseToken(String access_token) {
        Claims body = null;
        try {
            //提供 密钥解析token （验证token是否有效）
//            Jws<Claims> 是一个JWT的包装类，包含了JWT的头部和负载信息
//            Jwts.parserBuilder() 是解析token的构建器
//            setSigningKey 设置签名密钥
//            build 构建解析器
//            parseClaimsJws(access_token) 解析token
            Jws<Claims> claimsJws = Jwts.parserBuilder().setSigningKey(tokenSignKey).build().parseClaimsJws(access_token);
//            claimsJws.getBody()  获取负载信息
            body = claimsJws.getBody();
        } catch (Exception e) {
            throw new LeaseException(ResultCodeEnum.TOKEN_EXPIRED);
        }

        return body;
    }
}
